home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr40 / x1j4pk96.zip / MOTOROLA.C < prev    next >
Text File  |  1993-05-19  |  6KB  |  199 lines

  1. /* ************************************************************************
  2.  *
  3.  * Binary to hex converter for motorola format hex
  4.  *
  5.  * (C) By Dave Roberts G8KBB.
  6.  * This program is provided 'as is', with no warranty. It has been
  7.  * produced for use in self-tuition in amateur radio and is not
  8.  * to be used for commercial applications. It may be freely copied and
  9.  * used under these conditions.
  10.  *
  11.  * This version includes a bug fix attributable to KH6ILT
  12.  *
  13.  * Invocation :
  14.  *
  15.  *    MOTOROLA infile outfile [ hex_start_address ]
  16.  *
  17.  * Return codes : AS detailed in the source. 0 for success, error
  18.  *                codes 1 - 5 errors as detailed below.
  19.  *
  20.  *************************************************************************/
  21.  
  22. #include <stdio.h>
  23.  
  24. unsigned Address;        /* effective address of data */
  25. unsigned char Buffer[32786];    /* buffer for i/p data from file */
  26. unsigned char *Ptr;        /* pointer into buffer for reading */
  27. unsigned Count;            /* number of bytes left in buffer */
  28. FILE *Fpin, *Fpout;        /* input & output file handles */
  29.  
  30. /* ***********************************************************************
  31.  * this is the main program.
  32.  * It exits with an error code of 0 if all went correctly.
  33.  * With 1 for a syntax error
  34.  *      2 for an input file open error
  35.  *      3 for an output file open error
  36.  *      4 for an input file read error
  37.  *      5 for an output file write error
  38.  * **********************************************************************/
  39.  
  40. main( argc, argv )
  41. char *argv[];
  42. {
  43.     int ecode;        /* error code on exit from main loop */
  44.     char *tmpptr;        /* scratch pointer for strtol() */
  45.     int cont;        /* flag to say stop looping */
  46.  
  47.     Address = 0;        /* address is zero unless user inputs one */
  48.     Count = 0;        /* mark buffer as empty */
  49.     ecode = 0;        /* error code will be zero if all goes well */
  50.     Ptr = Buffer;        /* point to start of buffer */
  51.     cont = 1;        /* flag that makes main loop loop ! */
  52.  
  53.     printf("Motorola S record dump program, Version 2.0\n\n");
  54.  
  55.     /* we need an input file & an output file.
  56.      * A start address is optional
  57.      * so need 2 or 3 parameters !
  58.      */
  59.     if( argc < 3 || argc > 4 )
  60.     {
  61.         printf( "Error - usage is :\n    motorola infile outfile [ start-address ]\n");
  62.         exit( 1 );
  63.     }
  64.  
  65.     /* OK, we seem to have the parameters - so let's open the input
  66.      * file in BINARY !!!! mode.
  67.      * Error & exit if cannot.
  68.      */
  69.     if( ( Fpin = fopen( argv[1], "rb"  ) ) == NULL )
  70.     {
  71.         perror("Input file error ");
  72.         exit( 2 );
  73.     }
  74.  
  75.     /* Next, lets open the output file for write, in default mode
  76.      * Error & exit if cannot
  77.      */
  78.     if( ( Fpout = fopen( argv[2], "w" ) ) == NULL )
  79.     {
  80.         perror("Output file error ");
  81.         exit( 3 );
  82.     }
  83.  
  84.     /* Now the optional start address.
  85.      * WARNING - being a lazy sod, just take the last 16 bits
  86.      */
  87.     if( argc == 4 )
  88.         Address = strtol( argv[3], &tmpptr, 16 );
  89.  
  90.     /* output the file header record
  91.      */
  92.     fprintf( Fpout, "S00600004844521B\n" );
  93.  
  94.     /* MAIN LOOP - keep doing this until there is no more data
  95.      * or until an error occurs.
  96.      *
  97.      * Read a buffer full if there is less than 16 bytes left in buffer
  98.      * Crash out if there is a read error.
  99.      * Dump either 16 bytes, or whatever is left to dump
  100.      * Crash out if write error
  101.      * Exit anyway if there was less than 16 bytes ( as we did not 
  102.      * read any more
  103.      */
  104.     while( cont )
  105.     {
  106.         if( Count < 16 )
  107.         {
  108.             if( !getdata() )
  109.             {
  110.                 perror("Input file ");
  111.                 ecode = 4;
  112.                 break;
  113.             }
  114.         }
  115.         if( Count < 16 )
  116.             cont = 0;
  117.         if( !dump( Count >= 16 ? 16 : Count ) )
  118.         {
  119.             perror("Output file ");
  120.             ecode = 5;
  121.             break;
  122.         }
  123.     }
  124.  
  125.     /* dump trailing line
  126.      * close files
  127.      * and exit.
  128.      */
  129.     fprintf( Fpout, "S9030000FC\n" );
  130.     fclose( Fpin );
  131.     fclose( Fpout );
  132.     return( ecode );
  133. }
  134.  
  135. /* ***********************************************************************
  136.  * This function reads data from the input file.
  137.  * Firstly, if there is still a bit of data left in the buffer, move
  138.  * it down to the bottom of the buffer.
  139.  * Then point to the start of the buffer so we handle that data first.
  140.  * Now try to fill the buffer up.
  141.  * If we read less than we expected, just check to see that the reason
  142.  * was end of file & if not die horribly.
  143.  * Now check for file read errors for additional ways to die.
  144.  * Finally, update the byte counter to reflect the new buffer size & return
  145.  * a return of 0 means error, 1 means all went well.
  146.  * ***********************************************************************/
  147. getdata()
  148. {
  149.     unsigned int i;        /* temp store used for bytes actually read */
  150.  
  151.     if( Count != 0 )
  152.         memmove( Buffer, Ptr, Count );
  153.     Ptr = Buffer;
  154.     i = fread( Buffer+Count, sizeof( char ), sizeof(Buffer)-Count, Fpin );
  155.     if( i != sizeof(Buffer)-Count && !feof( Fpin ) )
  156.         return( 0 );
  157.     if( ferror( Fpin ) )
  158.         return( 0 );
  159.     Count += i;
  160.     return( 1 );
  161. }
  162.  
  163. /* ************************************************************************
  164.  * Dump function for a line of data.
  165.  * This outputs a single line of (num) bytes of data.
  166.  * It checks each write for an error.
  167.  * Firstly, it sends the line preamble, count, address and type.
  168.  * Then it sends each byte in turn.
  169.  * Finally it computes the checksum & sends that too.
  170.  * A return of 0 means error, a return of 1 means all went well.
  171.  * ***********************************************************************/
  172. dump( num )
  173. unsigned num;
  174. {
  175.     int i;            /* counter for number of bytes processed */
  176.     unsigned char csum;    /* checksum value for line of data */
  177.  
  178.     if( num == 0 )
  179.         return( 1 );
  180.     fprintf( Fpout, "S1%02X%04X", num + 3, Address );
  181.     if( ferror( Fpout ) )
  182.         return( 0 );
  183.     csum = num + 3 + ( (Address >> 8) & 0xff) + (Address & 0xff);
  184.     for( i=0; i<num; i++ )
  185.     {
  186.         fprintf( Fpout, "%02X", *Ptr );
  187.         if( ferror( Fpout ) )
  188.             return( 0 );
  189.         csum += *Ptr++;
  190.         Count--;
  191.         if( ! ++Address )
  192.             printf("WARNING. The address exceeded 0xffff.\n");
  193.     }
  194.     fprintf( Fpout, "%02X\n", (~csum) & 0xff );
  195.     if( ferror( Fpout ) )
  196.         return( 0 );
  197.     return( 1 );
  198. }
  199.